{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a name=\"top\"></a><img src=\"./source/SpinalHDL.png\" alt=\"SpinalHDL based on Scala\" style=\"width:320px;\" />"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Before running Spinal HDL code, be sure to load SpinalHDL Libraries  \n",
    "**Note** : This may be a little slow when the first time load, please wait a moment to download Lib from remote.)   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "val path = System.getProperty(\"user.dir\") + \"/source/load-spinal.sc\"\n",
    "interp.load.module(ammonite.ops.Path(java.nio.file.FileSystems.getDefault().getPath(path)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Assignement overlap\n",
    "SpinalHDL will check that no signal assignement completly erases a previous one.   \n",
    "The following code will throw the following error:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val a = UInt(8 bits)\n",
    "  a := 42\n",
    "  a := 66 //Erease the a := 42 :(\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A fix could be:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val a = UInt(8 bits)\n",
    "  a := 42\n",
    "  when(something){\n",
    "    a := 66\n",
    "  }\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "But in the case you really want to override the previous assignement (Yes, it could make sense in some cases), you can do the following:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val a = UInt(8 bits)\n",
    "  a := 42\n",
    "  a.allowOverride\n",
    "  a := 66\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Clock crossing violation\n",
    "SpinalHDL will check that every register of your design only depends (through some combinatorial logic) on registers which use the same or a synchronous clock domain. \n",
    "\n",
    "The following code will throw error:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val clkA = ClockDomain.external(\"clkA\")\n",
    "  val clkB = ClockDomain.external(\"clkB\")\n",
    "\n",
    "  val regA = clkA(Reg(UInt(8 bits)))   //PlayDev.scala:834\n",
    "  val regB = clkB(Reg(UInt(8 bits)))   //PlayDev.scala:835\n",
    "\n",
    "  val tmp = regA + regA                //PlayDev.scala:838\n",
    "  regB := tmp\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There are multiple possible fixes:\n",
    "### crossClockDomain tag\n",
    "The crossClockDomain tag can be used to say “It’s alright, don’t panic” to SpinalHDL"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val clkA = ClockDomain.external(\"clkA\")\n",
    "  val clkB = ClockDomain.external(\"clkB\")\n",
    "\n",
    "  val regA = clkA(Reg(UInt(8 bits)))\n",
    "  val regB = clkB(Reg(UInt(8 bits))).addTag(crossClockDomain)\n",
    "\n",
    "\n",
    "  val tmp = regA + regA\n",
    "  regB := tmp\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### setSyncronousWith\n",
    "You can also specify that two clock domains are syncronous together."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val clkA = ClockDomain.external(\"clkA\")\n",
    "  val clkB = ClockDomain.external(\"clkB\")\n",
    "  clkB.setSyncronousWith(clkA)\n",
    "\n",
    "  val regA = clkA(Reg(UInt(8 bits)))\n",
    "  val regB = clkB(Reg(UInt(8 bits)))\n",
    "\n",
    "\n",
    "  val tmp = regA + regA\n",
    "  regB := tmp\n",
    "}\n",
    "\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### BufferCC\n",
    "Signal Bits or Gray-coded Bits can use BufferCC to cross different clockDomain"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class syncRead2Write extends Component {\n",
    "  val io = new Bundle{\n",
    "    val pushClock, pushRst = in Bool()\n",
    "    val readPtr = in UInt(8 bits)\n",
    "  }\n",
    "  val pushCC = new ClockingArea(ClockDomain(io.pushClock, io.pushRst)) {\n",
    "    val pushPtrGray = RegNext(toGray(io.readPtr)) init(0)\n",
    "  }\n",
    "}\n",
    "showRtl(new syncRead2Write)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Combinational loop\n",
    "SpinalHDL will check that there are no combinatorial loops in the design.\n",
    "\n",
    "The following code will throw error:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val a = UInt(8 bits) //PlayDev.scala line 831\n",
    "  val b = UInt(8 bits) //PlayDev.scala line 832\n",
    "  val c = UInt(8 bits)\n",
    "  val d = UInt(8 bits)\n",
    "\n",
    "  a := b\n",
    "  b := c | d\n",
    "  d := a\n",
    "  c := 0\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A possible fix could be:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val a = UInt(8 bits) //PlayDev.scala line 831\n",
    "  val b = UInt(8 bits) //PlayDev.scala line 832\n",
    "  val c = UInt(8 bits)\n",
    "  val d = UInt(8 bits)\n",
    "\n",
    "  a := b\n",
    "  b := c | d\n",
    "  d := 42\n",
    "  c := 0\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### False-positive\n",
    "It should be said that SpinalHDL’s algorithm to detect combinatorial loops can be pessimistic, and it may give false positives. If it is giving a false positive, you can manualy disable loop checking on one signal of the loop like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val a = UInt(8 bits)\n",
    "  a := 0\n",
    "  a(1) := a(0) //False positive because of this line\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "could be fixed by :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val a = UInt(8 bits).noCombLoopCheck\n",
    "  a := 0\n",
    "  a(1) := a(0)\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It should also be said that assignments such as (a(1) := a(0)) can make some tools like Verilator unhappy. It may be better to use a Vec(Bool, 8) in this case"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Hierarchy violation\n",
    "\n",
    "SpinalHDL will check that signals are never accessed outside of the current component’s scope.\n",
    "\n",
    "The following signals can be read inside a component:\n",
    "\n",
    "- All directionless signals defined in the current component\n",
    "\n",
    "- All in/out/inout signals of the current component\n",
    "\n",
    "- All in/out/inout signals of children components\n",
    "\n",
    "In addition, the following signals can be assigned to inside a component:\n",
    "\n",
    "- All directionless signals defined in the current component\n",
    "\n",
    "- All out/inout signals of the current component\n",
    "\n",
    "- All in/inout signals of children components\n",
    "\n",
    "If a `HIERARCHY VIOLATION`error appears, it means that one of the above rules was violated.\n",
    "\n",
    "The following code will throw error:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val io = new Bundle {\n",
    "    val a = in UInt(8 bits)\n",
    "  }\n",
    "  val tmp = U\"x42\"\n",
    "  io.a := tmp\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A fix could be :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val io = new Bundle {\n",
    "    val a = out UInt(8 bits) // changed from in to out\n",
    "  }\n",
    "  val tmp = U\"x42\"\n",
    "  io.a := tmp\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Io bundle\n",
    "SpinalHDL will check that each io bundle contains only in/out/inout signals."
   ]
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "class TopLevel extends Component {\n",
    "  val io = new Bundle {\n",
    "    val a = UInt(8 bits)\n",
    "  }\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A fix could be:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val io = new Bundle {\n",
    "    val a = in UInt(8 bits)\n",
    "  }\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "But if for meta hardware description reasons you realy want io.a to be directionless, you can do:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val io = new Bundle {\n",
    "    val a = UInt(8 bits)\n",
    "  }\n",
    "  io.a.allowDirectionLessIo\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Latch detected\n",
    "SpinalHDL will check that no combinatorial signal will infer a latch during synthesis. In other words, that no combinatorial signals are partialy assigned."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val cond = in(Bool)\n",
    "  val a = UInt(8 bits)\n",
    "\n",
    "  when(cond){\n",
    "    a := 42\n",
    "  }\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A fix could be:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val cond = in(Bool)\n",
    "  val a = UInt(8 bits)\n",
    "\n",
    "  a := 0\n",
    "  when(cond){\n",
    "    a := 42\n",
    "  }\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## No driver on\n",
    "SpinalHDL will check that all combinatorial signals which have an impact on the design are assigned by something."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val result = out(UInt(8 bits))\n",
    "  val a = UInt(8 bits)\n",
    "  result := a\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A fix could be:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val result = out(UInt(8 bits))\n",
    "  val a = UInt(8 bits)\n",
    "  a := 42\n",
    "  result := a\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## NullPointerException\n",
    "NullPointerException is a Scala runtime reported error which can happen when a variable is accessed before it was initialised."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  a := 42\n",
    "  val a = UInt(8 bits)\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A fix could be:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val a = UInt(8 bits)\n",
    "  a := 42\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Issue explanation :**\n",
    "SpinalHDL is not a language, it is a Scala library, which means it obeys the same rules as the Scala general purpose programming language. When you run your SpinalHDL hardware description to generate the corresponding VHDL/Verilog RTL, your SpinalHDL hardware description will be executed as a Scala programm, and a will be a null reference until the program executes val a = UInt(8 bits), so trying to assign it before then will result in a NullPointerException."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Register defined as component input\n",
    "In SpinalHDL, you are not allowed to define a component that has a register as an input. The reasoning behind this is to prevent surprises when the user tries to drive the inputs of child components with the registered signal. If a registered input is desired, you will need to declare the unregistered input in the io bundle, and register the signal in the body of the component."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val io = new Bundle {\n",
    "    val a = in(Reg(UInt(8 bits)))\n",
    "  }\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val io = new Bundle {\n",
    "    val a = in UInt(8 bits)\n",
    "  }\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If a registered a is really wanted, it can be done like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val io = new Bundle {\n",
    "    val a = in UInt(8 bits)\n",
    "  }\n",
    "  val a = RegNext(io.a)\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Scope violation\n",
    "SpinalHDL will check that there are no signals assigned outside the scope they are defined in. This error isn’t easy to trigger as it requires some specific meta hardware description tricks."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val cond = Bool()\n",
    "\n",
    "  var tmp : UInt = null\n",
    "  when(cond){\n",
    "    tmp = UInt(8 bits)\n",
    "  }\n",
    "  tmp := U\"x42\"\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A fix could be:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val cond = Bool()\n",
    "\n",
    "  var tmp : UInt = UInt(8 bits)\n",
    "  when(cond){\n",
    "\n",
    "  }\n",
    "  tmp := U\"x42\"\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Spinal can’t clone class  ???\n",
    "This error happens when SpinalHDL wants to create a new datatype via the cloneOf function but isn’t able to do it. The reasons for this is nearly always because it can’t retreive the construction parameters of a Bundle."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "//cloneOf(this) isn't able to retreive the width value that was used to construct itself\n",
    "class RGB(width : Int) extends Bundle{\n",
    "  val r,g,b = UInt(width bits)\n",
    "}\n",
    "class TopLevel extends Component {\n",
    "  val tmp =  Stream(new RGB(8))  //Stream requires the capability to cloneOf(new RGB(8))\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A fix could be:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "case class RGB(width : Int) extends Bundle{\n",
    "  val r,g,b = UInt(width bits)\n",
    "}\n",
    "\n",
    "class TopLevel extends Component {\n",
    "  val tmp = Stream(RGB(8))\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Unassigned register\n",
    "SpinalHDL will check that all registers which impact the design have been assigned somewhere."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val result = out(UInt(8 bits))\n",
    "  val a = Reg(UInt(8 bits))\n",
    "  result := a\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A fix could be:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val result = out(UInt(8 bits))\n",
    "  val a = Reg(UInt(8 bits))\n",
    "  a := 42\n",
    "  result := a\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Register with only init  \n",
    "In some case, because of the design parameterization, it could make sense to generate a register which has no assignement but only a init statement."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel(something: Boolean) extends Component {\n",
    "  val result = out(UInt(8 bits))\n",
    "  val a = Reg(UInt(8 bits))  \n",
    "   \n",
    "  if(something){ \n",
    "    a := 32\n",
    "  }\n",
    "  result := a\n",
    "}\n",
    "showRtl(new TopLevel(false) )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To fix it you can ask SpinalHDL to transform the register into a combinatorial one if no assignement is present but it as a init statement:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel(something: Boolean) extends Component {\n",
    "  val result = out(UInt(8 bits))\n",
    "  val a = Reg(UInt(8 bits)).init(42).allowUnsetRegToAvoidLatch\n",
    "\n",
    "  if(something){   \n",
    "    a := 37   \n",
    "  }\n",
    "  result := a\n",
    "}\n",
    "showRtl(new TopLevel(false))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Unreachable is statement\n",
    "SpinalHDL will check all is statements in a switch are reachable."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val sel = UInt(2 bits)\n",
    "  val result = UInt(4 bits)\n",
    "  switch(sel){\n",
    "    is(0){ result := 4 }\n",
    "    is(1){ result := 6 }\n",
    "    is(2){ result := 8 }\n",
    "    is(3){ result := 9 }\n",
    "    is(0){ result := 2 } //Duplicated statement is statement !\n",
    "  }\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A fix could be:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val sel = UInt(2 bits)\n",
    "  val result = UInt(4 bits)\n",
    "  switch(sel){\n",
    "    is(0){ result := 4 }\n",
    "    is(1){ result := 6 }\n",
    "    is(2){ result := 8 }\n",
    "    is(3){ result := 9 }\n",
    "  }\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Width mismatch\n",
    "SpinalHDL will check that signals on the left and right side of assignments and operators are the same width."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val a = UInt(8 bits)\n",
    "  val b = UInt(4 bits)\n",
    "  b := a\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A fix could be:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val a = UInt(8 bits)\n",
    "  val b = UInt(4 bits)\n",
    "  b := a.resized\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###  Operator example\n",
    "The following code:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val a = UInt(8 bits)\n",
    "  val b = UInt(4 bits)\n",
    "  val result = a | b\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A fix could be:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TopLevel extends Component {\n",
    "  val a = UInt(8 bits)\n",
    "  val b = UInt(4 bits)\n",
    "  val result = a | (b.resized)\n",
    "}\n",
    "showRtl(new TopLevel)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Scala",
   "language": "scala",
   "name": "scala"
  },
  "language_info": {
   "codemirror_mode": "text/x-scala",
   "file_extension": ".scala",
   "mimetype": "text/x-scala",
   "name": "scala",
   "nbconvert_exporter": "script",
   "version": "2.12.8"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
